import json

import mws
import xmltodict
from django.http import QueryDict, HttpResponse
from django.shortcuts import render

# Create your views here.
from rest_framework import status, viewsets
from rest_framework.generics import ListAPIView, CreateAPIView, UpdateAPIView, GenericAPIView, DestroyAPIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.pagination import PageNumberPagination
from store.serializers import StoreListSerializer, NewStoreAddSerializer, UpdateStoreInfoSerializer, \
    DeleteStoreSerializer, SellerPerformanceReportSerializer, TimeFrameSerializer, PerformanceChecklistStatusSerializer, \
    PerformanceChecklistSerializer, OrderDefectsSerialzier, RateAndCountSerializer, OrderDefectMetricsSerialzier, \
    CustomerExperienceMetricsSerializer, TrackingInformationSerialzier, TrackingMetricsSerialzier, \
    BuyerSellerContactResponseTimeMetricsSerializer, ResponseTimeMetricsSerializer, CustomerServiceSerializer, \
    CustomerServiceMetricsSerializer, ReturnDissatisfactionSerializer, ReturnDissatisfactionMetricsSerializer, \
    ProductAuthenticityDataSerializer, ProductSafetyDataSerializer, ListingPolicyDataSerializer, \
    CustomerExperienceSerializer, IntellectualPropertyDataSerializer, StoreFinanceReportSerializer
from users.models import User
from .models import StoreManagement, UserAndStore, StoreFinance, PerformanceChecklistStatus, TimeFrame, RateAndCount, \
    OrderDefects, IntellectualPropertyData, ListingPolicyData, ProductSafetyData, ProductAuthenticityData, \
    ReturnDissatisfactionMetrics, ReturnDissatisfaction, CustomerServiceMetrics, CustomerService, ResponseTimeMetrics, \
    BuyerSellerContactResponseTimeMetrics, TrackingMetrics, TrackingInformation, CustomerExperienceMetrics, \
    CustomerExperience, OrderDefectMetrics, PerformanceChecklist


class ListPagination(PageNumberPagination):
    page_size = 10
    page_size_query_description = 'page_size'
    max_page_size = 100


class GetStoreList(ListAPIView):
    """获取店铺列表"""
    queryset = StoreManagement.objects.all()
    serializer_class = StoreListSerializer
    pagination_class = ListPagination


class StorenameExist(APIView):

    def post(self, request):
        """获取指定用户数量"""

        storename = request.POST.get('storename')

        try:
            user_count = StoreManagement.objects.filter(store=storename).count()
        except Exception as e:
            return Response({"error_msg": str(e)})
        data = {
            "user_count": user_count,
            "username": storename
        }

        return Response(data)


class NewStoreAdd(CreateAPIView):
    """增加新店铺"""
    serializer_class = NewStoreAddSerializer


class UpdateStoreInfo(GenericAPIView):
    """修改店铺信息"""
    queryset = StoreManagement.objects.all()
    serializer_class = UpdateStoreInfoSerializer

    def post(self, request):

        datas = request.data
        id = datas.get("id")
        try:
            store = StoreManagement.objects.get(id=id)
        except Exception as e:
            data = {"error_msg": str(e)}
            return Response(data,status=status.HTTP_400_BAD_REQUEST)
        serializer = UpdateStoreInfoSerializer(store, data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()


        return Response({"success_msg": "修改成功"})


class DeleteStore(GenericAPIView):
    """删除店铺"""
    queryset = StoreManagement.objects.all()
    serializer_class = DeleteStoreSerializer

    def post(self, request):
        serializer = DeleteStoreSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        try:
            store_info = StoreManagement.objects.get(store=serializer.data['store'])
        except Exception as e:
            # print(e)
            data = {"error_message": str(e)}
            return Response(data)

        store_info.delete()

        return Response({"success_msg": "删除成功"})


class GetStoreNameList(APIView):
    permission_classes = [IsAuthenticated]
    def get(self, request):
        """返回店铺列表"""
        user = request.user
        try:
            stores = UserAndStore.objects.filter(staff=user.id)
            # stores = StoreManagement.objects.all()
        except Exception as e:
            return Response({"error_msg": str(e)})
        store_list = [i.store.store for i in stores]
        return Response({"success_msg": store_list})

class StoreUnbindingAndEmpowerViewSet(viewsets.ViewSet):

    def unbinding(self,request):
        """店铺解绑"""
        params = request.query_params
        staff_id = params.get("staff_id")
        store_id = params.get("store_id")
        try:
            UserAndStore.objects.get(staff=staff_id,store=store_id).delete()
        except Exception as e:
            return Response({"error_msg":str(e)}, status=status.HTTP_400_BAD_REQUEST)

        return Response({"success_msg": "解绑成功"}, status=status.HTTP_200_OK)

    def lot_unbinding(self,request):
        """批量解绑店铺"""
        datas = request.data
        # print(datas)
        for i in datas:
            staff_id = i.get("staff_id")
            store_id = i.get("store_id")
            try:
                staff = User.objects.get(id=staff_id)
                store = StoreManagement.objects.filter(id__in=store_id)
            except Exception as e:
                return Response({"error_msg": str(e)}, status=status.HTTP_400_BAD_REQUEST)
            for i in store:
                try:
                    UserAndStore.objects.get(staff=staff, store=i).delete()
                except Exception as e:
                    return Response({"error_msg": str(e)}, status=status.HTTP_400_BAD_REQUEST)

        return Response({"success_msg": "批量解绑成功"})

    def empower(self,request):
        """店铺授权"""
        params = request.query_params
        store_id = params.get("store_id")
        staff_id = params.get("staff_id")
        try:
            staff = User.objects.get(id=staff_id)
            store = StoreManagement.objects.get(id=store_id)
        except Exception as e:
            return Response({"error_msg":str(e)}, status=status.HTTP_400_BAD_REQUEST)
        UserAndStore.objects.create(staff=staff, store=store)
        return Response({"success_msg": "绑定成功"}, status=status.HTTP_200_OK)

    def lot_empower(self,request):
        """批量店铺授权"""
        datas = request.data

        for i in datas:
            staff_id = i.get("staff_id")
            store_id = i.get("store_id")
            try:
                staff = User.objects.get(id=staff_id)
                store = StoreManagement.objects.filter(id__in=store_id)
            except Exception as e:
                return Response({"error_msg": str(e)}, status=status.HTTP_400_BAD_REQUEST)
            for i in store:
                try:
                    UserAndStore.objects.create(staff=staff, store=i)
                except Exception as e:
                    return Response({"error_msg": str(e)}, status=status.HTTP_507_INSUFFICIENT_STORAGE)
        return Response({"success_msg":"批量绑定成功"}, status=status.HTTP_201_CREATED)


class GetTrueFinanceViewSet(viewsets.ViewSet):

    def update_finance(self,request):
        StoreFinance.objects.all().delete()


        test = SellerPerformanceReport()
        test.command_def()

        return Response({"success_msg":"ok"},status=status.HTTP_201_CREATED)

    def get_finance_list(self, request):
        queryset = StoreManagement.objects.all()
        serializer = StoreFinanceReportSerializer(queryset, many=True)
        # serializer.is_valid(raise_exception=True)
        # print(serializer.data)
        return Response({"success_msg": serializer.data},status=status.HTTP_200_OK)


class SellerPerformanceReport:


    def __init__(self):
        self.access_key = 'AKIAITNXOMXBNOGOAHMQ'
        self.secret_key = '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'

    def get_store(self):
        stores = StoreManagement.objects.filter(store_type='MFN')
        return stores

    def get_report_list_in_mysql_for_one_store(self,store):
        report_list_in_mysql = StoreFinance.objects.filter(store__id=store.id)
        return [i.report_id for i in report_list_in_mysql]


    def get_report_list(self,store):
        x = mws.Reports(access_key=self.access_key, secret_key=self.secret_key, account_id=str(store.seller_id),
                        auth_token=str(store.mws_token))
        response = x.get_report_list(requestids=(), max_count="200", types=('_GET_V1_SELLER_PERFORMANCE_REPORT_',),
                                     acknowledged=None,
                                     fromdate=None, todate=None, next_token=None)

        xml_str = response.original
        dict_str = xmltodict.parse(xml_str)
        result = dict_str['GetReportListResponse']['GetReportListResult']
        if result.get("ReportInfo") is None:
            return []

        report_list = list()
        for i in result['ReportInfo']:

            report_list.append(i['ReportId'])
        print(report_list)
        return report_list

    def get_report_content(self,store,report_id):

        x = mws.Reports(access_key=self.access_key, secret_key=self.secret_key, account_id=str(store.seller_id),
                        auth_token=str(store.mws_token))
        try:
            # orders = x.list_orders(created_after=CreatedAfter, marketplaceids=marketplaceids)
            orders = x.get_report(report_id=report_id)
        except Exception as e:
            print(str(e))

        response_data = orders.original
        datas = xmltodict.parse(response_data)

        return datas


    def rateAndCount2mysql(self,rateAndCount):
        serializer_rateAndCount = RateAndCountSerializer(data=rateAndCount)
        serializer_rateAndCount.is_valid()
        rateAndCount_id = serializer_rateAndCount.save().id
        return rateAndCount_id

    def timeFrame2mysql(self,timeFrame):
        serializer_time = TimeFrameSerializer(data=timeFrame)
        serializer_time.is_valid()
        timeFrame_id = serializer_time.save().id

        return timeFrame_id


    def PerformanceChecklist2mysql(self,performanceChecklist,store_finance_id):

        for k,v in performanceChecklist.items():
            serializer_status = PerformanceChecklistStatusSerializer(data=v)
            serializer_status.is_valid(raise_exception=True)
            performanceChecklist[k] = serializer_status.save().id
        performanceChecklist['store_finance'] = store_finance_id
        serializer_list = PerformanceChecklistSerializer(data=performanceChecklist)
        serializer_list.is_valid()
        serializer_list.save()
        # PerformanceChecklist_id = PerformanceChecklist.objects.all().order_by('-id').first().id


    def OrderDefect2mysql(self,orderDefects,store_finance_id):
        orderDefects['store_finance'] = store_finance_id
        serializer_list = OrderDefectsSerialzier(data=orderDefects)
        serializer_list.is_valid()
        OrderDefects_id = serializer_list.save().id


        orderDefectMetrics = orderDefects.get("orderDefectMetrics")

        if not isinstance(orderDefectMetrics, list):
            orderDefectMetrics = [orderDefectMetrics]
        for one_orderDefectMetrics in orderDefectMetrics:
            one_orderDefectMetrics['orderDefects'] = OrderDefects_id
            one_orderDefectMetrics['timeFrame'] = self.timeFrame2mysql(one_orderDefectMetrics['timeFrame'])
            one_orderDefectMetrics['orderWithDefects'] = self.rateAndCount2mysql(one_orderDefectMetrics['orderWithDefects'])
            one_orderDefectMetrics['negativeFeedbacks'] = self.rateAndCount2mysql(one_orderDefectMetrics['negativeFeedbacks'])
            one_orderDefectMetrics['a_z_claims'] = self.rateAndCount2mysql(one_orderDefectMetrics['a_z_claims'])
            one_orderDefectMetrics['chargebacks'] = self.rateAndCount2mysql(one_orderDefectMetrics['chargebacks'])
            serializer = OrderDefectMetricsSerialzier(data=one_orderDefectMetrics)
            serializer.is_valid()
            serializer.save()

    def CustomerExperience2mysql(self,customerExperience,store_finance_id):
        customerExperience['store_finance'] = store_finance_id

        serializer_list = CustomerExperienceSerializer(data=customerExperience)
        serializer_list.is_valid(raise_exception=True)
        customerExperience_id = serializer_list.save().id
        customerExperienceMetrics = customerExperience.get("customerExperienceMetrics")
        if not isinstance(customerExperienceMetrics, list):
            customerExperienceMetrics = [customerExperienceMetrics]
        for one_customerExperienceMetrics in customerExperienceMetrics:
            one_customerExperienceMetrics['customerExperience'] = customerExperience_id
            one_customerExperienceMetrics['timeFrame'] = self.timeFrame2mysql(one_customerExperienceMetrics['timeFrame'])
            one_customerExperienceMetrics['lateShipment'] = self.rateAndCount2mysql(one_customerExperienceMetrics['lateShipment'])
            one_customerExperienceMetrics['preFulfillmentCancellation'] = self.rateAndCount2mysql(one_customerExperienceMetrics['preFulfillmentCancellation'])
            one_customerExperienceMetrics['refunds'] = self.rateAndCount2mysql(one_customerExperienceMetrics['refunds'])

            serializer = CustomerExperienceMetricsSerializer(data=one_customerExperienceMetrics)
            serializer.is_valid(raise_exception=True)
            serializer.save()

    def trackingInformation2mysql(self,trackingInformation,store_finance_id):
        trackingInformation['store_finance'] = store_finance_id
        serializer_list = TrackingInformationSerialzier(data=trackingInformation)
        serializer_list.is_valid()
        trackingInformation_id = serializer_list.save().id
        trackingMetrics = trackingInformation.get("trackingMetrics")
        if not isinstance(trackingMetrics, list):
            trackingMetrics = [trackingMetrics]
        for one_trackingMetrics in trackingMetrics:
            one_trackingMetrics['trackingInformation'] = trackingInformation_id
            one_trackingMetrics['timeFrame'] = self.timeFrame2mysql(one_trackingMetrics['timeFrame'])
            one_trackingMetrics['validTracking'] = self.rateAndCount2mysql(one_trackingMetrics['validTracking'])
            one_trackingMetrics['onTimeDelivery'] = self.rateAndCount2mysql(one_trackingMetrics['onTimeDelivery'])
            serializer = TrackingMetricsSerialzier(data=one_trackingMetrics)
            serializer.is_valid(raise_exception=True)
            serializer.save()
    def buyerSellerContactResponseTimeMetrics2mysql(self,buyerSellerContactResponseTimeMetrics,store_finance_id):

        buyerSellerContactResponseTimeMetrics['store_finance'] = store_finance_id
        serializer_list = BuyerSellerContactResponseTimeMetricsSerializer(data=buyerSellerContactResponseTimeMetrics)
        serializer_list.is_valid()
        buyerSellerContactResponseTimeMetrics_id = serializer_list.save().id

        responseTimeMetrics = buyerSellerContactResponseTimeMetrics.get("responseTimeMetrics")
        if not isinstance(responseTimeMetrics, list):
            responseTimeMetrics = [responseTimeMetrics]
        for one_responseTimeMetrics in responseTimeMetrics:
            one_responseTimeMetrics['responseTimeMetrics'] = buyerSellerContactResponseTimeMetrics_id
            one_responseTimeMetrics['timeFrame'] = self.timeFrame2mysql(one_responseTimeMetrics['timeFrame'])
            serializer = ResponseTimeMetricsSerializer(data=one_responseTimeMetrics)
            serializer.is_valid()
            serializer.save()
    def customerService2mysql(self,customerService,store_finance_id):
        customerService['store_finance'] = store_finance_id
        serializer_list = CustomerServiceSerializer(data=customerService)
        serializer_list.is_valid()
        customerService_id = serializer_list.save().id

        customerServiceMetrics = customerService.get("customerServiceMetrics")
        if not isinstance(customerServiceMetrics, list):
            customerServiceMetrics = [customerServiceMetrics]
        for one_customerServiceMetrics in customerServiceMetrics:
            one_customerServiceMetrics['customerServiceMetrics'] = customerService_id
            one_customerServiceMetrics['timeFrame'] = self.timeFrame2mysql(one_customerServiceMetrics['timeFrame'])
            one_customerServiceMetrics['customerServiceDissatisfaction'] = self.rateAndCount2mysql(one_customerServiceMetrics['customerServiceDissatisfaction'])

            serializer = CustomerServiceMetricsSerializer(data=one_customerServiceMetrics)
            serializer.is_valid()
            serializer.save()
    def returnDissatisfaction2mysql(self,returnDissatisfaction,store_finance_id):
        returnDissatisfaction['store_finance'] = store_finance_id

        serializer_list = ReturnDissatisfactionSerializer(data=returnDissatisfaction)
        serializer_list.is_valid(raise_exception=True)
        returnDissatisfaction_id = serializer_list.save().id

        returnDissatisfactionMetrics = returnDissatisfaction.get("returnDissatisfactionMetrics")
        if not isinstance(returnDissatisfactionMetrics, list):
            returnDissatisfactionMetrics = [returnDissatisfactionMetrics]
        for one_returnDissatisfactionMetrics in returnDissatisfactionMetrics:
            one_returnDissatisfactionMetrics['returnDissatisfactionMetrics'] = returnDissatisfaction_id
            one_returnDissatisfactionMetrics['timeFrame'] = self.timeFrame2mysql(one_returnDissatisfactionMetrics['timeFrame'])
            one_returnDissatisfactionMetrics['returnDissatisfaction'] = self.rateAndCount2mysql(one_returnDissatisfactionMetrics['returnDissatisfaction'])
            one_returnDissatisfactionMetrics['negativeReturnFeedback'] = self.rateAndCount2mysql(one_returnDissatisfactionMetrics['negativeReturnFeedback'])
            one_returnDissatisfactionMetrics['lateResponse'] = self.rateAndCount2mysql(one_returnDissatisfactionMetrics['lateResponse'])
            one_returnDissatisfactionMetrics['invalidRejection'] = self.rateAndCount2mysql(one_returnDissatisfactionMetrics['invalidRejection'])
            serializer = ReturnDissatisfactionMetricsSerializer(data=one_returnDissatisfactionMetrics)
            serializer.is_valid()
            serializer.save()

    def productAuthenticityData2mysql(self,productAuthenticityData,store_finance_id):
        productAuthenticityData['store_finance'] = store_finance_id
        productAuthenticityData['timeFrame'] = self.timeFrame2mysql(productAuthenticityData['timeFrame'])
        serializer_list = ProductAuthenticityDataSerializer(data=productAuthenticityData)
        serializer_list.is_valid(raise_exception=True)
        serializer_list.save()

    def productSafetyData2mysql(self,productSafetyData,store_finance_id):
        productSafetyData['store_finance'] = store_finance_id
        productSafetyData['timeFrame'] = self.timeFrame2mysql(productSafetyData['timeFrame'])
        serializer_list = ProductSafetyDataSerializer(data=productSafetyData)
        serializer_list.is_valid()
        serializer_list.save()

    def listingPolicyData2mysql(self,listingPolicyData,store_finance_id):
        listingPolicyData['store_finance'] = store_finance_id
        listingPolicyData['timeFrame'] = self.timeFrame2mysql(listingPolicyData['timeFrame'])
        serializer_list = ListingPolicyDataSerializer(data=listingPolicyData)
        serializer_list.is_valid()
        serializer_list.save()

    def intellectualPropertyData2mysql(self,intellectualPropertyData,store_finance_id):
        intellectualPropertyData['store_finance'] = store_finance_id
        intellectualPropertyData['timeFrame'] = self.timeFrame2mysql(intellectualPropertyData['timeFrame'])
        serializer_list = IntellectualPropertyDataSerializer(data=intellectualPropertyData)
        serializer_list.is_valid()
        serializer_list.save()



    def report_data2mysql(self, datas, report_id, store):
        # 1 存主表  获取主表id
        store_finance = StoreFinance.objects.create(report_id=report_id,store=store)
        store_finance_id = store_finance.id
        # 2 存副表
        # （1）副表1     PerformanceChecklist
        performanceChecklist = datas.get("performanceChecklist")
        self.PerformanceChecklist2mysql(performanceChecklist, store_finance_id)
        # （2）副表2    OrderDefects    先存OrderDefects
        orderDefects = datas.get("orderDefects")
        self.OrderDefect2mysql(orderDefects, store_finance_id)
        # （3）副表3    CustomerExperience
        customerExperience = datas.get("customerExperience")
        self.CustomerExperience2mysql(customerExperience, store_finance_id)
        # （4）副表4    TrackingInformation
        trackingInformation = datas.get("trackingInformation")
        self.trackingInformation2mysql(trackingInformation, store_finance_id)
        # （5）副表5    BuyerSellerContactResponseTimeMetrics
        buyerSellerContactResponseTimeMetrics = datas.get("buyerSellerContactResponseTimeMetrics")
        self.buyerSellerContactResponseTimeMetrics2mysql(buyerSellerContactResponseTimeMetrics, store_finance_id)
        # （6）副表6    CustomerService
        customerService = datas.get("customerService")
        self.customerService2mysql(customerService, store_finance_id)
        # （7）副表7    ReturnDissatisfaction
        returnDissatisfaction = datas.get("returnDissatisfaction")
        self.returnDissatisfaction2mysql(returnDissatisfaction, store_finance_id)
        # （8）副表8    ProductAuthenticityData
        productAuthenticityData = datas.get("productAuthenticityData")
        self.productAuthenticityData2mysql(productAuthenticityData, store_finance_id)
        # （9）副表9    ProductSafetyData
        productSafetyData = datas.get("productSafetyData")
        self.productSafetyData2mysql(productSafetyData, store_finance_id)
        # （10）副表10    ListingPolicyData
        listingPolicyData = datas.get("listingPolicyData")
        self.listingPolicyData2mysql(listingPolicyData, store_finance_id)
        # （11）副表11    IntellectualPropertyData
        intellectualPropertyData = datas.get("intellectualPropertyData")
        self.intellectualPropertyData2mysql(intellectualPropertyData, store_finance_id)


    def command_def(self):
        stores = self.get_store()
        for store in stores:
            report_list_in_mysql = self.get_report_list_in_mysql_for_one_store(store)
            report_list = self.get_report_list(store)
            # report_list = report_list[:2]    # 测试每次取2个
            for report_id in report_list:
                if report_id not in report_list_in_mysql:
                    report_content = self.get_report_content(store,report_id)
                    report_content = report_content['sellerPerformanceReports']['sellerPerformanceReport']
                    self.report_data2mysql(report_content,report_id,store)



